package com.shanjupay.common.utilbak;

import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.Map;

/**
 * http工具类
 */
@Component
public class HttpUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(HttpUtil.class);

    @Autowired
    private OkHttpClient okHttpClient;


    public static String get(String url, Map<String, String> queries)throws Exception {
        return get(url,queries,null);
    }

    /**
     * get
     *
     * @param url     请求的url
     * @param queries 请求的参数，在浏览器？后面的数据，没有可以传null
     * @return
     */
    public static String get(String url, Map<String, String> queries,Map<String,String> headers)throws Exception {
        StringBuffer sb = new StringBuffer(url);
        if (queries != null && queries.keySet().size() > 0) {
            boolean firstFlag = true;
            Iterator iterator = queries.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry<String, String>) iterator.next();
                if (firstFlag) {
                    sb.append("?" + entry.getKey() + "=" + entry.getValue());
                    firstFlag = false;
                } else {
                    sb.append("&" + entry.getKey() + "=" + entry.getValue());
                }
            }
        }

        Request.Builder builder = new Request.Builder()
                .url(sb.toString());

        if(headers!=null && headers.size() > 0){
            headers.forEach((k,v)->builder.header(k,v));
        }

        Request request = builder.build();
        Response response = null;
        try {
            response = instance.okHttpClient.newCall(request).execute();
            int status = response.code();
            if (response.isSuccessful()) {
                return response.body().string();
            }
            throw new Exception("get请求失败,responseCode="+status+"responseBody="+response.body().string());
        } finally {
            if (response != null) {
                try{
                    response.close();
                }catch (Exception e){
                }
            }
        }
    }

    public static String post(String url, Map<String, String> params)throws Exception {
        return post(url,params,null);
    }

    /**
     * post
     *
     * @param url    请求的url
     * @param params post form 提交的参数
     * @return
     */
    public static String post(String url, Map<String, String> params,Map<String,String> headers)throws Exception {
        FormBody.Builder builder = new FormBody.Builder();
        //添加参数
        if (params != null && params.keySet().size() > 0) {
            for (String key : params.keySet()) {
                builder.add(key, params.get(key));
            }
        }

        Request.Builder rb = new Request.Builder().url(url);

        if(headers!=null && headers.size() > 0){
            headers.forEach((k,v)->rb.header(k,v));
        }

        Request request = rb
                .post(builder.build())
                .build();
        Response response = null;
        try {
            response = instance.okHttpClient.newCall(request).execute();
            int status = response.code();
            if (response.isSuccessful()) {
                return response.body().string();
            }
            throw new Exception("post请求失败,responseCode="+status+"responseBody="+response.body().string());
        }finally {
            if (response != null) {
                try{
                    response.close();
                }catch (Exception e){
                }
            }
        }
    }

    public static String postJsonParams(String url, String jsonParams)throws Exception{
        return postJsonParams(url,jsonParams,null);
    }

    /**
     * Post请求发送JSON数据....{"name":"zhangsan","pwd":"123456"}
     * 参数一：请求Url
     * 参数二：请求的JSON
     * 参数三：请求回调
     */
    public static String postJsonParams(String url, String jsonParams,Map<String,String> headers)throws Exception {
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonParams);
        Request.Builder builder = new Request.Builder().url(url);

        if(headers!=null && headers.size() > 0){
            headers.forEach((k,v)->builder.header(k,v));
        }

        Request request = builder.post(requestBody).build();
        Response response = null;
        try {
            response = instance.okHttpClient.newCall(request).execute();
            int status = response.code();
            if (response.isSuccessful()) {
                return response.body().string();
            }
            throw new Exception("json格式post请求失败,responseCode="+status+"responseBody="+response.body().string());
        } finally {
            if (response != null) {
                try{
                    response.close();
                }catch (Exception e){
                }
            }
        }
    }

    public static String putJsonParams(String url, String jsonParams)throws Exception{
        return putJsonParams(url,jsonParams,null);
    }

    /**
     * put请求发送JSON数据....{"name":"zhangsan","pwd":"123456"}
     * 参数一：请求Url
     * 参数二：请求的JSON
     * 参数三：请求回调
     */
    public static String putJsonParams(String url, String jsonParams,Map<String,String> headers)throws Exception {
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonParams);
        Request.Builder builder = new Request.Builder().url(url);

        if(headers!=null && headers.size() > 0){
            headers.forEach((k,v)->builder.header(k,v));
        }

        Request request = builder.put(requestBody).build();
        Response response = null;
        try {
            response = instance.okHttpClient.newCall(request).execute();
            int status = response.code();
            if (response.isSuccessful()) {
                return response.body().string();
            }
            throw new Exception("json格式post请求失败,responseCode="+status+"responseBody="+response.body().string());
        } finally {
            if (response != null) {
                try{
                    response.close();
                }catch (Exception e){
                }
            }
        }
    }

    public static String deleteJsonParams(String url, String jsonParams)throws Exception{
        return deleteJsonParams(url,jsonParams,null);
    }

    /**
     * put请求发送JSON数据....{"name":"zhangsan","pwd":"123456"}
     * 参数一：请求Url
     * 参数二：请求的JSON
     * 参数三：请求回调
     */
    public static String deleteJsonParams(String url, String jsonParams,Map<String,String> headers)throws Exception {
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonParams);
        Request.Builder builder = new Request.Builder().url(url);

        if(headers!=null && headers.size() > 0){
            headers.forEach((k,v)->builder.header(k,v));
        }

        Request request = builder.delete(requestBody).build();
        Response response = null;
        try {
            response = instance.okHttpClient.newCall(request).execute();
            int status = response.code();
            if (response.isSuccessful()) {
                return response.body().string();
            }
            throw new Exception("json格式post请求失败,responseCode="+status+"responseBody="+response.body().string());
        } finally {
            if (response != null) {
                try{
                    response.close();
                }catch (Exception e){
                }
            }
        }
    }

    /**
     * Post请求发送xml数据....
     * 参数一：请求Url
     * 参数二：请求的xmlString
     * 参数三：请求回调
     */
    public static String postXmlParams(String url, String xml) throws Exception {
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/xml; charset=utf-8"), xml);
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        Response response = null;
        try {
            response = instance.okHttpClient.newCall(request).execute();
            int status = response.code();
            if (response.isSuccessful()) {
                return response.body().string();
            }
            throw new Exception("xml格式post请求失败,responseCode="+status+"responseBody="+response.body().string());
        }finally {
            if (response != null) {
                try{
                    response.close();
                }catch (Exception e){
                }
            }
        }
    }


    /**
     * post
     *
     * @param url    请求的url
     * @param params post form 提交的参数
     * @return
     */
    public static String postWithFile(String url, Map<String, Object> params,Map<String,String> headers)throws Exception {
        MultipartBody.Builder builder = new MultipartBody.Builder();
        //设置类型
        builder.setType(MultipartBody.FORM);
        //添加参数
        if (params != null && params.keySet().size() > 0) {
            params.entrySet().stream().forEach(e->{
                if(e.getValue() == null)
                    return;
                if(e.getValue() instanceof File){
                    File file = (File) e.getValue();
                    Path path = Paths.get(file.getAbsolutePath());
                    String type = "multipart/form-data";
                    try {
                        type = Files.probeContentType(path);
                    } catch (IOException e1) {
                        LOGGER.error("获取文件类型出错",e1);
                    }
                    builder.addFormDataPart(e.getKey(), file.getName(), RequestBody.create(MediaType.parse(type), file));
                    return;
                }
                builder.addFormDataPart(e.getKey(),e.getValue().toString());
            });
        }

        Request.Builder rb = new Request.Builder().url(url);

        if(headers!=null && headers.size() > 0){
            headers.forEach((k,v)->rb.header(k,v));
        }

        Request request = rb
                .post(builder.build())
                .build();
        Response response = null;
        try {
            response = instance.okHttpClient.newCall(request).execute();
            int status = response.code();
            if (response.isSuccessful()) {
                return response.body().string();
            }
            throw new Exception("post请求失败,responseCode="+status+"responseBody="+response.body().string());
        }finally {
            if (response != null) {
                try{
                    response.close();
                }catch (Exception e){

                }
            }
        }
    }


    private static HttpUtil instance;

    @PostConstruct
    public void init(){
        instance = this;
    }

    /**
     * 获取请求ip信息
     *
     * @param request
     * @return [参数、异常说明]
     * @see [类、类#方法、类#成员]
     */
    public static String getIp(HttpServletRequest request) throws Exception {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
            if(ip.equals("127.0.0.1") || ip.equals("0:0:0:0:0:0:0:1")){
                //根据网卡取本机配置的IP
                InetAddress inet = InetAddress.getLocalHost();
                ip= inet.getHostAddress();
            }
        }
        //对于通过多个代理的情况，第一个IP为客户端真实IP,多个IP按照','分割
        if(ip!=null && ip.length()>15){ //"***.***.***.***".length() = 15
            if(ip.indexOf(",")>0){
                ip = ip.substring(0,ip.indexOf(","));
            }
        }
        return ip;
    }
}
